import { triplitClient } from "@renderer/client";
import { useQuery, useQueryOne } from "@triplit/react";
import { useMemo } from "react";
import type {
  CollectionName,
  QueryConfig,
  QueryData,
  QueryDataSingle,
  QueryOneConfig,
  QueryResult,
} from "../types";

/**
 * 基础查询Hook - 支持多条记录查询
 */
export function useStandardQuery<
  T extends CollectionName,
  TSelect = QueryData<T>,
>(
  queryFn: () => ReturnType<typeof triplitClient.query<T>>,
  options: QueryConfig<T, TSelect> = {},
): QueryResult<TSelect> {
  const { enabled = true, select } = options;

  // 使用 Triplit 的 useQuery hook
  const baseQuery = queryFn();
  const query = enabled
    ? baseQuery
    : triplitClient.query(baseQuery.collectionName as T).Limit(0);
  const { results, fetching, error } = useQuery(
    triplitClient,
    // @ts-expect-error - 处理条件查询的类型问题
    query,
  );

  // 转换数据
  const transformedData = useMemo(() => {
    if (!enabled || !results) return undefined;
    const rawData = Array.from(results.values()) as QueryData<T>;
    return select ? select(rawData) : (rawData as TSelect);
  }, [enabled, results, select]);

  return {
    data: transformedData as TSelect,
    isLoading: enabled && fetching && transformedData === undefined,
    isFetching: enabled && fetching,
    error: enabled ? error || null : null,
  };
}

/**
 * 单条记录查询Hook - 支持单条记录查询
 */
export function useStandardQueryOne<
  T extends CollectionName,
  TSelect = QueryDataSingle<T>,
>(
  queryFn: () => ReturnType<typeof triplitClient.query<T>>,
  options: QueryOneConfig<T, TSelect> = {},
): QueryResult<TSelect> {
  const { enabled = true, select } = options;

  // 使用 Triplit 的 useQueryOne hook
  const baseQuery = queryFn();
  const query = enabled
    ? baseQuery
    : triplitClient.query(baseQuery.collectionName as T).Limit(0);
  const { result, fetching, error } = useQueryOne(
    triplitClient,
    // @ts-expect-error - 处理条件查询的类型问题
    query,
  );

  // 转换数据
  const transformedData = useMemo(() => {
    if (!enabled || result === undefined) return undefined;
    const rawData = result as QueryDataSingle<T>;
    return select ? select(rawData) : (rawData as TSelect);
  }, [enabled, result, select]);

  return {
    data: transformedData as TSelect,
    isLoading: enabled && fetching && transformedData === undefined,
    isFetching: enabled && fetching,
    error: enabled ? error || null : null,
  };
}
